package com.jellyfishumbrella;

import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.vector.Vector3f;

import com.jellyfishumbrella.GL.LandscapeGLMesh;
import com.jellyfishumbrella.GL.RendererGL;

public class GameLogic {
	public static double	SCALING				= 1;
	public static float		GL_SCALE			= 1.0f / 10.0f;
	int						landscapePoints		= 300;
	public LandscapeData	island;
	public LandscapeGLMesh	islandGL;

	public static Boolean	gameRunning			= true;
	/**
	 * The time at which the last rendering loop started from the point of
	 * view of the game logic
	 */
	private long			lastLoopTime		= getTime();
	private long			lastFpsTime			= 0;
	private int				fps;
	private static long		timerTicksPerSecond	= Sys.getTimerResolution();
	private boolean			lastMouseDown		= false;

	public RendererGL		renderGL;

	public GameLogic() {
		island = new LandscapeData();
		island.createlandscape(600 * SCALING, landscapePoints);
		islandGL = new LandscapeGLMesh(island);
		// islandGL.initVertexData();
	}

	public void update() {

	}

	/**
	 * Get the high resolution time in milliseconds
	 * 
	 * @return The high resolution time in milliseconds
	 */
	public static long getTime() {
		// we get the "timer ticks" from the high resolution timer
		// multiply by 1000 so our end result is in milliseconds
		// then divide by the number of ticks in a second giving
		// us a nice clear time in milliseconds
		return (Sys.getTime() * 1000) / timerTicksPerSecond;
	}

	public void gameLoop() {
		while (gameRunning) {
			// Game Logic
			processKeyboard();
			processMouse();
			gameLogic();

			// Game Rendering
			renderGL.render(islandGL);

			// update window contents
			Display.update();
		}
	}

	/**
	 * Notification that a frame is being rendered. Responsible for
	 * running game logic and rendering the scene.
	 */
	public void gameLogic() {
		int mx = Mouse.getX(), my = Mouse.getY();
		Display.sync(100);

		// work out how long its been since the last update, this
		// will be used to calculate how far the entities should
		// move this loop
		long delta = getTime() - lastLoopTime;
		lastLoopTime = getTime();
		lastFpsTime += delta;
		fps++;

		// update our FPS counter if a second has passed
		if (lastFpsTime >= 1000) {
			// Display.setTitle(renderGL.WINDOW_TITLE + " (FPS: " + fps +
			// "; mx: " + mx + "; my: " + my + ")  pos: " +
			// Math.round(camera._pos.x) + "|" + Math.round(camera._pos.y) + "|"
			// + Math.round(camera._pos.z) + "  rot: "
			// + Math.round(camera._rot.x) + "|" + Math.round(camera._rot.y) +
			// "|" + Math.round(camera._rot.z));
			lastFpsTime = 0;
			fps = 0;
		}

		// if escape has been pressed, stop the game
		if (Display.isCloseRequested() || Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
			gameRunning = false;
		}

		renderGL.camera.update();

		update();
	}

	public void processKeyboard() {
		if (Keyboard.isCreated()) {
			if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
				renderGL.camera.CREEP = true;
			} else {
				renderGL.camera.CREEP = false;
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
				renderGL.camera.moveForward();
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
				renderGL.camera.moveLeft();
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
				renderGL.camera.moveBackward();
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
				renderGL.camera.moveRight();
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_C)) {
				renderGL.camera.moveDown();
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_V)) {
				renderGL.camera.moveUp();
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_F)) {
				renderGL.camera.isFlying = !renderGL.camera.isFlying;
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_P)) {
				// world.prebuildFieldsAround(camera.currFieldCoord.i,camera.currFieldCoord.j,0);
			}
		}
	}

	public void processMouse() {
		if (Keyboard.isCreated()) {
			int mx = Mouse.getX(), my = Mouse.getY();
			float diffX = Mouse.getDX() * 0.1f;
			float diffY = Mouse.getDY() * 0.1f;
			renderGL.camera._rot.x -= (float) diffY;
			if (renderGL.camera._rot.x < -90) {
				renderGL.camera._rot.x = -90;
			} else if (renderGL.camera._rot.x > 90) {
				renderGL.camera._rot.x = 90;
			}
			renderGL.camera._rot.y += (float) diffX;

			// Selection Magic
			if (Mouse.isButtonDown(0) && !lastMouseDown) {
				mx = renderGL.DISPLAY_WIDTH / 2;
				my = renderGL.DISPLAY_HEIGHT / 2;
				Vector3f worldPos = renderGL.screenTo3D(mx, my);// DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2);
			}

			lastMouseDown = Mouse.isButtonDown(0);
		}
	}
}